package org.footballmanager.pandafootball.system.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import lombok.extern.slf4j.Slf4j;
import org.footballmanager.pandafootball.common.configure.AmqpConfig;
import org.footballmanager.pandafootball.common.constants.Constants;
import org.footballmanager.pandafootball.system.domain.FootSociatyInfo;
import org.footballmanager.pandafootball.system.domain.FootUser;
import org.footballmanager.pandafootball.system.domain.FootZnx;
import org.footballmanager.pandafootball.system.form.impl.FootZnxSearchForm;
import org.footballmanager.pandafootball.system.mapper.FootZnxMapper;
import org.footballmanager.pandafootball.system.service.FootUserService;
import org.footballmanager.pandafootball.system.service.FootZnxService;
import org.footballmanager.pandafootball.system.service.PhotoService;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.support.CorrelationData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.ui.Model;
import tk.mybatis.mapper.entity.Example;

import javax.servlet.http.HttpServletRequest;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
import java.util.UUID;

@Slf4j
@Service("footZnxService")
public class FootZnxServiceImpl extends ServiceImpl<FootZnx> implements FootZnxService {
    @Autowired
    private FootZnxMapper footZnxMapper;
    @Autowired
    private FootUserService footUserService;
    @Autowired
    private PhotoService photoService;
    @Autowired
    private RabbitTemplate rabbitTemplate;

    /**
     * 发送站内信
     *
     * @param sender  发送者主键
     * @param reciver 接收者主键
     * @param content 内容
     * @param logo    logo
     * @param url     地址
     * @param request 请求
     */
    @Override
    public void sendZnx(Long sender, Long reciver, String content, Long logo, String url, HttpServletRequest request) {
        if (reciver == null) {
            List<FootUser> users = footUserService.getAllWithoutAdmin(null);
            if (users == null || users.isEmpty()) {
                return;
            }
            for (FootUser user : users) {
                sendMQ(sender, user.getId(), content, logo, url, request);
            }
        } else {
            sendMQ(sender, reciver, content, logo, url, request);
        }
    }

    /**
     * 发送战队站内信
     *
     * @param sender  用户主键 发送者
     * @param list    接收者列表
     * @param content 内容
     * @param logo    接收者队标
     * @param url     对应url
     * @param request 请求
     */
    @Override
    public void sendSociatyZnx(Long sender, List<FootSociatyInfo> list, String content, Long logo, String url, HttpServletRequest request) {
        if (list == null || list.isEmpty()) {
            return;
        }
        for (FootSociatyInfo footSociatyInfo : list) {
            sendMQ(sender, footSociatyInfo.getUserId(), content, logo, url, request);
        }
    }

    /**
     * 发送mq
     *
     * @param sender  发送者主键
     * @param resiver 接收者主键
     * @param content 内容
     * @param logo    logo
     * @param url     地址
     * @param request 请求
     */
    private void sendMQ(Long sender, Long resiver, String content, Long logo, String url, HttpServletRequest request) {
        FootZnx znx = this.saveNewZnx(sender, resiver, content, logo, url, request);
        CorrelationData correlationId = new CorrelationData(UUID.randomUUID().toString());
        JSONObject obj = new JSONObject();
        obj.put("type", 1);
        obj.put("content", JSONObject.toJSON(znx));
        rabbitTemplate.convertAndSend(AmqpConfig.EXCHANGE, AmqpConfig.ROUTINGKEY, obj.toString(), correlationId);
    }

    /**
     * 保存新的站内信信息
     *
     * @param sender  发送者
     * @param reciver 接收者
     * @param content 内容
     * @param logo    logo
     * @param url     地址
     * @param request 请求
     * @return 新站内信实体类
     */
    private FootZnx saveNewZnx(Long sender, Long reciver, String content, Long logo, String url, HttpServletRequest request) {
        FootZnx znx = new FootZnx();
        znx.setSender(sender);
        znx.setSenderName(footUserService.get(sender).getNike());
        znx.setResiver(reciver);
        znx.setResiverName(footUserService.get(reciver).getNike());
        znx.setSendTime(new Date());
        znx.setReaded(false);
        znx.setContent(content);
        znx.setLogo(logo);
        if (logo != null) {
            znx.setLogoUrl(photoService.get(logo).getUrl());
        }
        znx.setUrl(url);
        this.save(znx, request);
        return znx;
    }

    /**
     * 根据用户主键查找所有对应的站内信信息
     *
     * @param userId 用户主键
     * @return 站内信信息列表
     */
    @Override
    public List<FootZnx> findZnxsByUserId(Long userId) {
        Example example = new Example(FootZnx.class);
        Example.Criteria criteria = example.createCriteria();
        Example.Criteria criteria2 = example.createCriteria();
        criteria.andEqualTo("sender", userId);
        criteria2.andEqualTo("resiver", userId);
        example.or(criteria2);
        criteria.andEqualTo("delFlag", 0);
        return this.findall(example);
    }

    /**
     * 根据用户主键标记所有站内信为已读
     *
     * @param userId  用户主键
     * @param request 请求
     */
    @Override
    public void readAll(Long userId, HttpServletRequest request) {
        List<FootZnx> list = this.findZnxsByUserId(userId);
        if (list != null && !list.isEmpty()) {
            for (FootZnx znx : list) {
                znx.setReaded(true);
                this.updateNotNull(znx, request);
            }
        }
    }

    /**
     * 翻页方法
     *
     * @param footZnxSearchForm 条件
     * @return 列表
     */
    @Override
    public List<FootZnx> findall(FootZnxSearchForm footZnxSearchForm) {
        return footZnxMapper.findall(footZnxSearchForm);
    }

    /**
     * 根据主键获取记录
     *
     * @param id 主键
     * @return 记录
     */
    @Override
    public FootZnx get(Serializable id) {
        return footZnxMapper.findById(id);
    }

    /**
     * 读取站内信
     *
     * @param id      站内信主键
     * @param request 请求
     * @return 成功或失败
     */
    @Override
    public String znxyd(Long id, HttpServletRequest request) {
        FootZnx znx = this.get(id);
        if (znx != null) {
            znx.setReaded(true);
            this.updateNotNull(znx, request);
            return Constants.OK;
        }
        return Constants.ERROR;
    }

    /**
     * 查询
     *
     * @param entityname        实体类名
     * @param map               参数
     * @param footZnxSearchForm 条件
     */
    @Override
    public void search(String entityname, Model map, FootZnxSearchForm footZnxSearchForm) {
        map.addAttribute(String.format(Constants.FORMNAME, entityname), footZnxSearchForm);
        Page<FootZnx> page = PageHelper.startPage(footZnxSearchForm.getPageIndex(), footZnxSearchForm.getPageSize());
        List<FootZnx> list = this.findall(footZnxSearchForm);
        map.addAttribute(Constants.PI, page.toPageInfo());
        map.addAttribute(String.format(Constants.LISTENTITY, entityname), list);
    }

    /**
     * 删除所有
     *
     * @param footZnxSearchForm 条件
     * @param request           请求
     */
    @Override
    public void deleteAll(FootZnxSearchForm footZnxSearchForm, HttpServletRequest request) {
        if (footZnxSearchForm.getSelectIds() != null) {
            String[] result = footZnxSearchForm.getSelectIds().split(Constants.COMMA);
            for (String id : result) {
                this.delete(Long.parseLong(id), request);
            }
        }
    }

    /**
     * 设置站内信状态为已读
     *
     * @param id      站内信主键
     * @param request 请求
     * @return 站内信实体
     */
    @Override
    public FootZnx read(Long id, HttpServletRequest request) {
        FootZnx znx = this.get(id);
        if (znx != null) {
            znx.setReaded(true);
            this.updateNotNull(znx, request);
        }
        return znx;
    }

    /**
     * 根据用户主键删除所有记录
     *
     * @param userId  用户主键
     * @param request 请求
     */
    @Override
    public void deleteByUserId(Long userId, HttpServletRequest request) {
        //删除收件箱
        List<FootZnx> znxList = this.findZnxsByUserId(userId);
        if (znxList != null && !znxList.isEmpty()) {
            for (FootZnx fz : znxList) {
                this.delete(fz.getId(), request);
            }
        }
    }
}
